package com.spring.sd.ignore;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.stereotype.Component;

/**
 * InstantiationAwareBeanPostProcessor扩展了BeanPostProcessor
 *
 *
 */
@Component
public class InstantiationAwareBPP implements InstantiationAwareBeanPostProcessor{

    /**
     * BPP的接口
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (StringUtils.equals("a", beanName)) {
            System.out.println(">>>>> 在Bean属性装配后执行postProcessBeforeInitialization() ");
        }
        return InstantiationAwareBeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    /**
     * BPP的接口
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (StringUtils.equals("a", beanName)) {
            System.out.println(">>>>> 在Bean的Init相关初始化完毕后执行postProcessAfterInitialization() ");
        }
        return InstantiationAwareBeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }


    /**
     * 在Bean实例化之前，调用此方法；
     * 该方法传入目标Bean类型与BeanName;该方法可以返回一个该Bean类型的对象，或对该Bean的一个代理对象；
     * 当该方法返回了实例化对象后，后续的所有Bean实例化与初始化的动作将不再进行。
     * 只会调用后续的BeanPostProcessor#postProcessAfterInitialization()方法
     * @param beanClass
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {

        if (StringUtils.equals("a", beanName)) {
            System.out.println(">>>>> 执行Bean实例化之前，执行postProcessBeforeInstantiation() ");
        }
        //return InstantiationAwareBeanPostProcessor.super.postProcessBeforeInstantiation(beanClass, beanName);
        return null;
    }


    /**
     * 在Bean实例化之后，调用此方法；该方法传入还没有装配属性的Bean对象以及BeanName。
     * 如果该方法返回true，则将跳过后续的属性装配动作，一般应该返回true
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if (StringUtils.equals("a", beanName)) {

            System.out.println(">>>>> 执行Bean实例化之后执行postProcessAfterInstantiation()");
        }

        //return InstantiationAwareBeanPostProcessor.super.postProcessAfterInstantiation(bean, beanName);
        return true;
    }


    /**
     * 在Bean实例化之后，装配属性之前，调用此方法；该方法传入在配置期间所配的PropertyValues以及BeanName。
     * 该方法返回的PropertyValues将最终装配到Bean对象中。
     * @param pvs
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        if (StringUtils.equals("a", beanName)) {

            System.out.println(">>>>> 执行Bean属性装配前执行postProcessProperties()");
        }

        return InstantiationAwareBeanPostProcessor.super.postProcessProperties(pvs, bean, beanName);
    }
}
